package com.kgc.warehouse.system.shiro;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;

import com.kgc.warehouse.system.entity.*;
import com.kgc.warehouse.system.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;

import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class CustomerRealm extends AuthorizingRealm {
    @Autowired(required = false)
    private UserMapper userMapper;
    @Autowired(required = false)
    private DeptMapper deptMapper;
    @Autowired(required = false)
    private UserRoleMapper userRoleMapper;
    @Autowired(required = false)
    private RoleMapper roleMapper;

    @Autowired(required = false)
    private RolePermissionMapper rolePermissionMapper;
    @Autowired(required = false)
    private PermissionMapper permissionMapper;

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        // 用户授权  根据用户名查询用户权限信息   角色  权限字符串
        String primaryPrincipal = (String) principalCollection.getPrimaryPrincipal();
        // 根据用户名 查询用户id

        log.info(primaryPrincipal+"===============");
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getLoginname,primaryPrincipal);
        User user = userMapper.selectOne(userLambdaQueryWrapper);
        Integer id = user.getId();
        //根据用户id  查询用户角色id
        LambdaQueryWrapper<UserRole> userRoleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userRoleLambdaQueryWrapper.eq(UserRole::getUid,id);
        List<UserRole> userRoles = userRoleMapper.selectList(userRoleLambdaQueryWrapper);
        // 根据用户角色id 查询角色名称
        List<Integer> roleIds = userRoles.stream().map(userRole -> {
            return userRole.getRid();
        }).collect(Collectors.toList());
        LambdaQueryWrapper<Role> roleLambdaQueryWrapper = new LambdaQueryWrapper<>();
        roleLambdaQueryWrapper.in(Role::getId,roleIds);
        List<Role> roles = roleMapper.selectList(roleLambdaQueryWrapper);

        List<String> roleNames = roles.stream().map(role -> {
            return role.getName();
        }).collect(Collectors.toList());
        // 角色授权
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addRoles(roleNames);
        // 根据角色id  查询角色权限关联表
        LambdaQueryWrapper<RolePermission> rolePermissionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        rolePermissionLambdaQueryWrapper.in(RolePermission::getRid,roleIds);
        List<RolePermission> rolePermissions = rolePermissionMapper.selectList(rolePermissionLambdaQueryWrapper);
        //根据权限id查询权限详细信息
        List<Integer> perIds = rolePermissions.stream().map(rolePermission -> {
            return rolePermission.getPid();
        }).collect(Collectors.toList());
        LambdaQueryWrapper<Permission> permissionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        permissionLambdaQueryWrapper.in(Permission::getId,perIds);
        List<Permission> permissions = permissionMapper.selectList(permissionLambdaQueryWrapper);

        List<String> percodes = permissions.stream().map(permission -> {
            return permission.getPercode();
        }).collect(Collectors.toList());
        // 添加权限字符串
        simpleAuthorizationInfo.addStringPermissions(percodes);
        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        UsernamePasswordToken token=(UsernamePasswordToken)authenticationToken;
        String username = token.getUsername();
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getLoginname,username);
        User user = userMapper.selectOne(userLambdaQueryWrapper);
        System.out.println("user = " + user);

        if (ObjectUtils.isNotEmpty(user))
        {
            if (user.getAvailable()!=1)
            {
                throw new LockedAccountException();
            }
            SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(user.getLoginname(), user.getPwd(), ByteSource.Util.bytes(user.getSalt()), this.getName());
            return  simpleAuthenticationInfo;
        }
        return null;
    }
}
